#pragma once
#include<iostream>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#include<strings.h>
#include<fstream>
#define HTTP_VERSION "HTTP/1.0"
#define HOME_PAGE "wwwroot/index.html"
#define PAGE_404 "wwwroot/404.html"

namespace ns_Http
{
    class HttpServer
    {
    private:
        uint16_t port;
        int listen_sock;
    public:
        HttpServer(uint16_t _port):port(_port),listen_sock(-1){}
        ~HttpServer()
        {
            if(listen_sock>=0) close(listen_sock);
        }
        void InitHttpServer()
        {
            listen_sock=socket(AF_INET,SOCK_STREAM,0);
            if(listen_sock<0)
                exit(2);
            struct sockaddr_in local;
            socklen_t len=sizeof(local);
            bzero(&local,len);
            local.sin_family=AF_INET;
            local.sin_port=htons(port);
            local.sin_addr.s_addr=INADDR_ANY;
            if(bind(listen_sock,(struct sockaddr*)&local,len)<0)
                exit(3);
            if(listen(listen_sock,5)<0)
                exit(4);
        }
        static void* Routine(void* args)
        {
            int sock=*((int*)args);
            delete (int*)args;
            pthread_detach(pthread_self());
            
            //逻辑处理
            std::cout<<">-------------------------------begin-------------------------------<sock:"<<sock<<std::endl;
            char buffer[1024]={0};
            ssize_t s=recv(sock,buffer,sizeof(buffer)-1,0);
            if(s>0)
            {
                std::cout<<buffer<<std::endl;
            }
            std::cout<<">--------------------------------end--------------------------------<sock:"<<sock<<std::endl;
            
            std::string response;
            std::ifstream in(HOME_PAGE,std::ios::in|std::ios::binary);
            std::string body;
            std::string line;
            if(!in.is_open())//打开失败则发送404页面
            {  
                std::ifstream _in(PAGE_404,std::ios::in|std::ios::binary);
                while(getline(_in,line))
                    body+=line;
                response += "HTTP/1.0 404 Not Found\n";
                response += "Content-Type: text/html\n";
                response += ("Content-Length: " + std::to_string(body.size()) + "\n");
                response += "Set-Cookie: sessionid=123456\n"; //添加Set-Cookie字段
                response += "\n";
                response += body;
                send(sock, response.c_str(), response.size(), 0);
            }
            else//打开成功则发送首页页面
            {
                while(getline(in,line))
                    body+=line;
                response += "HTTP/1.0 200 OK\n";
                response += "Content-Type: text/html\n";
                response += ("Content-Length: " + std::to_string(body.size()) + "\n");
                response += "Set-Cookie: sessionid=123456\n"; //添加Set-Cookie字段
                response += "\n";
                response += body;
                send(sock, response.c_str(), response.size(), 0);
            }
            //make response
            //std::string body = "<html><head><meta charset=\"UTF-8\"></head><body><h1>hello world</h1><p>测试测试！！！</p></body></html>";
            // std::string response = HTTP_VERSION;
            // response += " 200 OK\n";
            // response += "Content-Type: text/html\n";
            // response += ("Content-Length: " + std::to_string(body.size()) + "\n");
            // response += "\n";
            // response += body;
            // send(sock, response.c_str(), response.size(), 0);

            // //构建HTTP响应
			// std::string response = "HTTP/1.0 307 Temporary Redirect\n"; //状态行
			// response += "Location: https://coca1cole.blog.csdn.net/\n"; //跳转页面
			// response += "\n"; //空行

			// send(sock, response.c_str(), response.size(), 0);
            close(sock);
            return nullptr;
        } 
        void Loop()
        {
            while(true)
            {
                struct sockaddr_in peer;
                socklen_t len=sizeof(peer);
                bzero(&peer,len);
                int sock=accept(listen_sock,(struct sockaddr*)&peer,&len);
                if(sock<0)
                    continue;
                pthread_t tid;
                int* p=new int(sock);
                pthread_create(&tid,nullptr,Routine,p);
            }
        }
    };
}
